#!/bin/sh 

source /usr/voltaire/common.sh
LOG_MAX_LINES=1024

log()
{
	if [ -z $log_file ] ; then
		echo $* 
	else
		echo "$(date +"%D %R") $*" >> $log_file
	fi
}

get_ib_if()
{
	gid=$(cat /sys/class/infiniband/$dev_name/ports/$port_num/gids/0|tr -d :)
	for ib in /sys/class/net/ib? ; do
		ib_addr=$(cat $ib/address|tr -d :)
		ib_addr_gid=${ib_addr:8:32}
		if [ $gid = $ib_addr_gid ] ; then
			echo $(basename $ib)
			break
		fi
	done
}

usage()
{
	log usage: "<--dev dev-name> <--port port-num> [--startif] [--overwrite] [--backup] [--logfile log-file] [--fake] [--nocolor]"
	exit 1
}


overwrite=
backup=
method_dhcp=1
nopurge=0

while [[ ! -z "$1" ]]
do
	case $1 in
	--startif)
		start=-start
		shift
		;;
	--overwrite)
		overwrite=-overwrite
		shift
		;;
	--backup)
		backup=-backup
		shift
		;;
	--fake)
		fake=echo
		shift
		;;
	--nocolor)
		nocolor=-nocolor
		shift
		;;
	--static)
		method_dhcp=0
		shift
		;;
	--dev)
		dev_name=$2
		shift 2
		;;
	--conf)
		source $2
		shift 2
		;;
	--port)
		port_num=$2
		shift 2
		;;
	--nopurge)
		nopurge=1
		shift
		;;
	--logfile)
		log_file=$2
		shift 2
		;;
	*)
		log "unknown option $1"
		usage
		exit
	;;
	esac
done


if [ ! -z $log_file ] && [ -f $log_file ]
then
	n_log_lines=$(wc -l $log_file|cut -f1 -d" ")
	[ $n_log_lines -ge $LOG_MAX_LINES ] && rm -f $log_file
fi

if [ -z $dev_name ]
then
	log ERROR: device name not specified
	exit 1
fi

if [ -z $port_num ]
then
	log ERROR: port num not specified
	exit 1
fi

if [ ! -d /sys/class/infiniband/$dev_name ]
then
	log ERROR: no entry for $dev_name under /sys/class/infiniband/
	exit 1
fi

if [ ! -d /sys/class/infiniband/$dev_name/ports/$port_num ]
then
	log ERROR: no entry for $port_num under /sys/class/infiniband/$dev_name/ports/
	exit 1
fi

# sometimes users don't want the pkey low byte in their network address
# by default, we DO use the pkey, for backward compatibility
if [ -z $GVD_NETWORK_USE_PKEY ] || [[ "$GVD_NETWORK_USE_PKEY" == [yY] ]]
then
	use_pkey="-usepkey"
else
	use_pkey=""
fi

ib_if=$(get_ib_if)
if [ -z $ib_if ]
then
	log ERROR: parent IB interface is unknown
	exit 1
fi

eval network=\$GVD_CHILD_IF_NETWORK_${ib_if}

if ( test $method_dhcp -eq 0 && test -z $network )
then
	log ERROR: no network found for $ib_if in configuration
	exit 1
fi

rm -rf /tmp/gvd-$$
mkdir /tmp/gvd-$$

cp $netscript_dir/ifcfg-$ib_if.???? /tmp/gvd-$$ 2>/dev/null


sysfs_pkey_base=/sys/class/infiniband/$dev_name/ports/$port_num/pkeys
for (( i=0; i<64; i++ ))
do
	pkey=$(cat $sysfs_pkey_base/$i|cut -f2 -dx)
	if [ $pkey != "0000" ] && [ $pkey != "ffff" ]
	then
		if [ $method_dhcp -ne 0 ]
		then
			cmdout=$($fake /usr/local/bin/ib-config-as-eth -dhcp -ib $ib_if.$pkey $overwrite $backup $nocolor $start 2>/dev/null)
		else
			cmdout=$($fake /usr/local/bin/ib-config-as-eth -network $network $use_pkey -ib $ib_if.$pkey $overwrite $backup $nocolor $start 2>/dev/null)
		fi
		if [ $? -ne 0 ]
		then
			log ERROR: failed to configure $ib_if.$pkey $cmdout
		else
			log Configuration of $ib_if.$pkey succeeded.
			rm -f /tmp/gvd-$$/ifcfg-$ib_if.$pkey 
		fi
	fi
done

# bring down previous interfaces if necessary
old_scripts=$(ls /tmp/gvd-$$/ifcfg-* 2>/dev/null)
if [ ! -z "$old_scripts" ]
then
	sleep 3
	for f in $old_scripts ; do 
		f=$(basename $f)
		ib=$(echo $f|cut -f2 -d-)
		cp /tmp/gvd-$$/$f $netscript_dir/
		ifdown $ib
		rm -f $netscript_dir/$f
	done
fi

rm -rf /tmp/gvd-$$/
exit 0

